home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / Open via Map / Open via Map Source / Source / Open via Map Extension.c next >
Encoding:
Text File  |  2000-06-24  |  11.0 KB  |  522 lines

  1. // Open via Map Extension.c
  2.  
  3. #include "Open via Map.h"
  4.  
  5. #include <MoreDesktopMgr.h>
  6.  
  7. #include <InternetConfig.h>
  8.  
  9. Boolean gQuit;
  10. Boolean gIsActive;
  11. ICInstance gIConfig;
  12.  
  13. static void Initialize(void)
  14. {
  15.     InitGraf(&qd.thePort);
  16.     MaxApplZone();
  17. }
  18.  
  19. static OSErr DoQuit(void)
  20. {
  21.     gQuit = true;
  22.     
  23.     return noErr;
  24. }
  25.  
  26. static OSErr GotRequiredParams(const AppleEvent *theEvent)
  27. {
  28.     OSErr theErr;
  29.     DescType theType;
  30.     Size theSize;
  31.     
  32.     theErr = AEGetAttributePtr(theEvent, keyMissedKeywordAttr, typeWildCard, &theType,
  33.         NULL, 0, &theSize);
  34.     
  35.     if (theErr == errAEDescNotFound)
  36.         theErr = noErr;
  37.     else
  38.         theErr = errAEParamMissed;
  39.     
  40.     return theErr;
  41. }
  42.  
  43. static Boolean FindMapping(FSSpec *theSpec, OSType *theOwner)
  44. {
  45.     Boolean isFound;
  46.     OSStatus theStatus;
  47.     ICMapEntry theEntry;
  48.     
  49.     isFound = false;
  50.     
  51.     theStatus = ICMapFilename(gIConfig, theSpec->name, &theEntry);
  52.     
  53.     if (theStatus == noErr)
  54.     {
  55.         isFound = true;
  56.         
  57.         if (theOwner != NULL)
  58.             *theOwner = theEntry.fileCreator;
  59.     }
  60.     
  61.     return isFound;
  62. }
  63.  
  64. static Boolean FindActiveProcessID(OSType theCreator, ProcessSerialNumber *thePSN)
  65. {
  66.     Boolean isFound;
  67.     ProcessInfoRec theInfo;
  68.     FSSpec theProcessSpec;
  69.     Str31 theName;
  70.     
  71.     isFound = false;
  72.     
  73.     thePSN->highLongOfPSN = 0;
  74.     thePSN->lowLongOfPSN = kNoProcess;
  75.     
  76.     while ((!isFound) && (GetNextProcess(thePSN) == noErr))
  77.     {
  78.         theInfo.processInfoLength = sizeof(theInfo);
  79.         theInfo.processName = (StringPtr) &theName;
  80.         theInfo.processAppSpec = &theProcessSpec;
  81.         
  82.         if (GetProcessInformation(thePSN, &theInfo) == noErr)
  83.         {
  84.             if (theCreator == theInfo.processSignature)
  85.                 isFound = true;
  86.         }
  87.     }
  88.     
  89.     if (!isFound)
  90.     {
  91.         thePSN->highLongOfPSN = 0;
  92.         thePSN->lowLongOfPSN = kNoProcess;
  93.     }
  94.     
  95.     return isFound;
  96. }
  97.  
  98. static OSErr DoOpenDocument(FSSpec *theSpec)
  99. {
  100.     OSErr theErr;
  101.     Boolean isFound;
  102.     OSType theCreator;
  103.     ProcessSerialNumber thePSN;
  104.     AEAddressDesc theTarget;
  105.     AppleEvent theOpenEvent;
  106.     AEDesc theAppParms;
  107.     AEDescList theAliases;
  108.     AliasHandle theNewAlias;
  109.     LaunchParamBlockRec pb;
  110.     FSSpec theAppSpec;
  111.     
  112.     FindMapping(theSpec, &theCreator);
  113.     
  114.     isFound = FindActiveProcessID(theCreator, &thePSN);
  115.     
  116.     theErr = noErr;
  117.     
  118.     if (isFound)
  119.         theErr = SetFrontProcess(&thePSN);
  120.     
  121.     if (theErr == noErr)
  122.         theErr = AECreateDesc(typeProcessSerialNumber, &thePSN, sizeof(thePSN),
  123.             &theTarget);
  124.     
  125.     if (theErr == noErr)
  126.     {
  127.         theErr = AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments, &theTarget,
  128.             kAutoGenerateReturnID, kAnyTransactionID, &theOpenEvent);
  129.         
  130.         AEDisposeDesc(&theTarget);
  131.         
  132.         if (theErr == noErr)
  133.         {
  134.             theErr = AECreateList(NULL, 0, false, &theAliases);
  135.             
  136.             if (theErr == noErr)
  137.             {
  138.                 theErr = NewAlias(NULL, theSpec, &theNewAlias);
  139.                 
  140.                 if (theErr == noErr)
  141.                 {
  142.                     HLock((Handle) theNewAlias);
  143.                     
  144.                     theErr = AEPutPtr(&theAliases, 0, typeAlias, *theNewAlias,
  145.                         GetHandleSize((Handle) theNewAlias));
  146.                     
  147.                     DisposeHandle((Handle) theNewAlias);
  148.                 }
  149.                 
  150.                 if (theErr == noErr)
  151.                     theErr = AEPutParamDesc(&theOpenEvent, keyDirectObject, &theAliases);
  152.                     
  153.                 AEDisposeDesc(&theAliases);
  154.             }
  155.             
  156.             if (theErr == noErr)
  157.             {
  158.                 if (isFound)
  159.                     theErr = AESend(&theOpenEvent, NULL, kAENoReply + kAECanInteract,
  160.                         kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
  161.                 else
  162.                 {
  163.                     theErr = FSpDTGetAPPL(NULL, 0, theCreator, &theAppSpec);
  164.                     
  165.                     if (theErr == noErr)
  166.                         theErr = AECoerceDesc(&theOpenEvent, typeAppParameters, &theAppParms);
  167.                     
  168.                     if (theErr == noErr)
  169.                     {
  170.                         HLock(theAppParms.dataHandle);
  171.                         
  172.                         pb.launchBlockID = extendedBlock;
  173.                         pb.launchEPBLength = extendedBlockLen;
  174.                         pb.launchFileFlags = 0;
  175.                         pb.launchControlFlags = launchContinue + launchNoFileFlags;
  176.                         pb.launchAppSpec = &theAppSpec;
  177.                         pb.launchAppParameters = (AppParameters *) *theAppParms.dataHandle;
  178.                         
  179.                         theErr = LaunchApplication(&pb);
  180.                         
  181.                         AEDisposeDesc(&theAppParms);
  182.                     }
  183.                 }
  184.             }
  185.             
  186.             AEDisposeDesc(&theOpenEvent);
  187.         }
  188.     }
  189.     
  190.     return theErr;
  191. }
  192.  
  193. static pascal OSErr DoHandleInterceptOpen(const AppleEvent *theEvent, AppleEvent *theReply,
  194.     UInt32 refCon)
  195. {
  196. #pragma unused(refCon)
  197.     
  198.     OSErr theErr;
  199.     OSStatus theStatus;
  200.     Boolean areAnySpecial;
  201.     long numItems;
  202.     long theIndex;
  203.     AEDesc theApplication;
  204.     AEDescList theDocuments;
  205.     AEKeyword theKeyword;
  206.     DescType theType;
  207.     Size theSize;
  208.     FSSpec theSpec;
  209.     EventRecord theModEvent;
  210.     
  211.     areAnySpecial = false;
  212.     
  213.     EventAvail(0, &theModEvent);
  214.     
  215.     if (gIsActive && ((theModEvent.modifiers & alphaLock) == 0))
  216.     {
  217.         theErr = AEGetParamDesc(theEvent, 'APPL', typeWildCard, &theApplication);
  218.         
  219.         if (theErr == noErr)
  220.             AEDisposeDesc(&theApplication);
  221.         else if (theErr == errAEDescNotFound)
  222.         {
  223.             theErr = AEGetParamDesc(theEvent, keySelection, typeAEList, &theDocuments);
  224.             
  225.             if (theErr == noErr)
  226.             {
  227.                 theErr = GotRequiredParams(theEvent);
  228.                 
  229.                 if (theErr == noErr)
  230.                     theErr = AECountItems(&theDocuments, &numItems);
  231.                 
  232.                 theStatus = ICBegin(gIConfig, icReadOnlyPerm);
  233.                 
  234.                 for (theIndex = 1;
  235.                     (!areAnySpecial) && (theErr == noErr) && (theIndex <= numItems); theIndex++)
  236.                 {
  237.                     theErr = AEGetNthPtr(&theDocuments, theIndex, typeFSS, &theKeyword, &theType,
  238.                         &theSpec, sizeof(theSpec), &theSize);
  239.                     
  240.                     if (theErr == noErr)
  241.                         areAnySpecial = FindMapping(&theSpec, NULL);
  242.                 }
  243.                 
  244.                 if (areAnySpecial)
  245.                 {
  246.                     for (theIndex = 1; (theErr == noErr) && (theIndex <= numItems); theIndex++)
  247.                     {
  248.                         theErr = AEGetNthPtr(&theDocuments, theIndex, typeFSS, &theKeyword, &theType,
  249.                             &theSpec, sizeof(theSpec), &theSize);
  250.                         
  251.                         if (theErr == noErr)
  252.                             theErr = DoOpenDocument(&theSpec);
  253.                     }
  254.                 }
  255.                 
  256.                 theStatus = ICEnd(gIConfig);
  257.                 
  258.                 AEDisposeDesc(&theDocuments);
  259.             }
  260.         }
  261.     }
  262.     
  263.     if (theReply != NULL)
  264.         AEPutKeyPtr(theReply, keyAEData, typeBoolean, &areAnySpecial, sizeof(areAnySpecial));
  265.     
  266.     return theErr;
  267. }
  268.  
  269. static pascal OSErr DoHandleOpenApplication(const AppleEvent *theEvent,
  270.     AppleEvent *theReply, UInt32 refCon)
  271. {
  272. #pragma unused(theReply, refCon)
  273.     OSErr theErr;
  274.     
  275.     theErr = GotRequiredParams(theEvent);
  276.     
  277.     return theErr;
  278. }
  279.  
  280. static pascal OSErr DoHandleActiveChange(const AppleEvent *theEvent, AppleEvent *theReply,
  281.     UInt32 refCon)
  282. {
  283. #pragma unused(theReply, refCon)
  284.     OSErr theErr;
  285.     DescType theType;
  286.     Size theSize;
  287.     Boolean isActive;
  288.     
  289.     theErr = AEGetParamPtr(theEvent, keyDirectObject, typeBoolean, &theType, &isActive,
  290.         sizeof(isActive), &theSize);
  291.     
  292.     if (theErr == noErr)
  293.     {
  294.         theErr = GotRequiredParams(theEvent);
  295.         
  296.         if (theErr == noErr)
  297.             gIsActive = isActive;
  298.     }
  299.     
  300.     return theErr;
  301. }
  302.  
  303. static pascal OSErr DoHandleOpenPrint(const AppleEvent *theEvent, Boolean isOpen)
  304. {
  305. #pragma unused(isOpen)
  306.     OSErr theErr;
  307.     AEDescList theDocuments;
  308.     
  309.     theErr = AEGetParamDesc(theEvent, keyDirectObject, typeAEList, &theDocuments);
  310.     
  311.     if (theErr == noErr)
  312.     {
  313.         theErr = GotRequiredParams(theEvent);
  314.         
  315.         AEDisposeDesc(&theDocuments);
  316.     }
  317.     
  318.     return theErr;
  319. }
  320.  
  321. static pascal OSErr DoHandleOpenDocuments(const AppleEvent *theEvent, AppleEvent *theReply,
  322.     UInt32 refCon)
  323. {
  324. #pragma unused(theReply, refCon)
  325.     OSErr theErr;
  326.     
  327.     theErr = DoHandleOpenPrint(theEvent, true);
  328.     
  329.     return theErr;
  330. }
  331.  
  332. static pascal OSErr DoHandlePrintDocuments(const AppleEvent *theEvent, AppleEvent *theReply,
  333.     UInt32 refCon)
  334. {
  335. #pragma unused(theReply, refCon)
  336.     OSErr theErr;
  337.     
  338.     theErr = DoHandleOpenPrint(theEvent, false);
  339.     
  340.     return theErr;
  341. }
  342.  
  343. static pascal OSErr DoHandleQuit(const AppleEvent *theEvent, AppleEvent *theReply,
  344.     UInt32 refCon)
  345. {
  346. #pragma unused(theReply, refCon)
  347.     OSErr theErr;
  348.     
  349.     theErr = GotRequiredParams(theEvent);
  350.     
  351.     if (theErr == noErr)
  352.         theErr = DoQuit();
  353.     
  354.     return theErr;
  355. }
  356.  
  357. static void InstallEventHandlers(void)
  358. {
  359.     OSErr theErr;
  360.     
  361.     theErr = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
  362.         NewAEEventHandlerProc(&DoHandleOpenApplication), 0, false);
  363.     
  364.     if (theErr == noErr)
  365.         theErr = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
  366.             NewAEEventHandlerProc(&DoHandleOpenDocuments), 0, false);
  367.     
  368.     if (theErr == noErr)
  369.         theErr = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
  370.             NewAEEventHandlerProc(&DoHandlePrintDocuments), 0, false);
  371.     
  372.     if (theErr == noErr)
  373.         theErr = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
  374.             NewAEEventHandlerProc(&DoHandleQuit), 0, false);
  375.     
  376.     if (theErr == noErr)
  377.         theErr = AEInstallEventHandler(kOpenViaMapEventClass, kActiveChange,
  378.             NewAEEventHandlerProc(&DoHandleActiveChange), 0, false);
  379. }
  380.  
  381. static void DoHighLevelEvent(EventRecord *theEvent)
  382. {
  383.     OSErr theErr;
  384.     
  385.     theErr = AEProcessAppleEvent(theEvent);
  386. }
  387.  
  388. static void DoEvent(EventRecord *theEvent)
  389. {
  390.     switch (theEvent->what)
  391.     {
  392.         case kHighLevelEvent:
  393.             DoHighLevelEvent(theEvent);
  394.             break;
  395.     }
  396. }
  397.  
  398. static void DoIdle(EventRecord *theEvent)
  399. {
  400. #pragma unused(theEvent)
  401. }
  402.  
  403. static void MainEventLoop(void)
  404. {
  405.     Boolean gotEvent;
  406.     UInt32 theSleep;
  407.     EventRecord theEvent;
  408.     
  409.     theSleep = GetCaretTime();
  410.     
  411.     while (!gQuit)
  412.     {
  413.         gotEvent = WaitNextEvent(everyEvent, &theEvent, theSleep, NULL);
  414.         
  415.         if (gotEvent)
  416.             DoEvent(&theEvent);
  417.         else
  418.             DoIdle(&theEvent);
  419.     }
  420. }
  421.  
  422. static OSErr GetActive(void)
  423. {
  424.     OSErr theErr;
  425.     FSSpec theSpec;
  426.     short refNum;
  427.     Preferences **thePreferences;
  428.     
  429.     gIsActive = true;
  430.     
  431.     theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder,
  432.         &theSpec.vRefNum, &theSpec.parID);
  433.     
  434.     if (theErr == noErr)
  435.     {
  436.         GetIndString(theSpec.name, kPreferencesStrxID, kPrefNameIndex);
  437.         
  438.         refNum = FSpOpenResFile(&theSpec, fsRdPerm);
  439.         theErr = ResError();
  440.         
  441.         if (theErr == noErr)
  442.         {
  443.             thePreferences = (Preferences **) Get1Resource(kPreferencesType, kPreferencesID);
  444.             
  445.             if (thePreferences && ((**thePreferences).theVersion == kPreferencesVersion))
  446.                 gIsActive = (**thePreferences).isActive;
  447.             
  448.             CloseResFile(refNum);
  449.         }
  450.     }
  451.     
  452.     return theErr;
  453. }
  454.  
  455. static pascal OSStatus UserSwitching(OSType theMessage, void *theArg, void *theUserRefCon)
  456. {
  457. #pragma unused(theArg, theUserRefCon)
  458.     
  459.     if (theMessage == kFolderManagerNotificationMessageUserLogIn)
  460.         GetActive();
  461.     else if (theMessage == kFolderManagerNotificationMessageUserLogOut)
  462.         gIsActive = false;
  463.     
  464.     return noErr;
  465. }
  466.  
  467. void main(void)
  468. {
  469.     OSErr theErr;
  470.     OSStatus theStatus;
  471.     long theResponse;
  472.     AEEventHandlerUPP theHandlerUPP;
  473.     FolderManagerNotificationUPP theNotifyUPP;
  474.     
  475.     gQuit = false;
  476.     
  477.     Initialize();
  478.     
  479.     InstallEventHandlers();
  480.     
  481.     theErr = GetActive();
  482.     
  483.     theHandlerUPP = NewAEEventHandlerUPP(&DoHandleInterceptOpen);
  484.     theErr = AEInstallEventHandler(kAEFinderSuite, kAEInterceptOpen, theHandlerUPP, 0, true);
  485.     
  486.     if (theErr == noErr)
  487.     {
  488.         theErr = Gestalt(gestaltMultipleUsersState, &theResponse);
  489.         
  490.         if ((theErr == noErr) && (**((short **) theResponse) > 0))
  491.         {
  492.             theNotifyUPP = NewFolderManagerNotificationUPP(&UserSwitching);
  493.             theErr = FolderManagerRegisterNotificationProc(theNotifyUPP, NULL, 0);
  494.         }
  495.         else
  496.         {
  497.             theErr = noErr;
  498.             theNotifyUPP = NULL;
  499.         }
  500.         
  501.         theStatus = ICStart(&gIConfig, kOpenViaMapExtensionCode);
  502.         
  503.         if (theStatus == noErr)
  504.         {
  505.             theStatus = ICFindConfigFile(gIConfig, 0, NULL);
  506.             
  507.             if (theStatus == noErr)
  508.                 MainEventLoop();
  509.             
  510.             theStatus = ICStop(gIConfig);
  511.         }
  512.         
  513.         if (theNotifyUPP)
  514.         {
  515.             theErr = FolderManagerUnregisterNotificationProc(theNotifyUPP, 0);
  516.             DisposeFolderManagerNotificationUPP(theNotifyUPP);
  517.         }
  518.         
  519.         theErr = AERemoveEventHandler(kAEFinderSuite, kAEInterceptOpen, theHandlerUPP, true);
  520.         DisposeAEEventHandlerUPP(theHandlerUPP);
  521.     }
  522. }